/** TODO:
 * 新添加的属性 [-]
 * 嵌套对象 [-]
 * 修改旧的对象不会触发watcher [-]
 * 数组、数组嵌套对象 [-]
 * 修改整个parent会触发下层 [-]
 * 重复绑定同一对象: 已经被proxy过了（设置过dep） [-]
 * nextTick [-]
 * deep
 * 计算属性（lazy）
 */

// Test 1: 对象键值修改
// const target = {
//   a: 1,
//   b: 2,
//   c: {
//     d: 1,
//   }
// };

// const data = proxy(target);

// const watcher = watch(() => {
//   return data.a + data.b + data.c.d;
// }, (oldVal, value) => {
//   console.log('watch 1 callback', oldVal, value);
// });

// watch(() => {
//   return data.c.d;
// }, (oldVal, value) => {
//   console.log('watch 2 callback', oldVal, value);
// });

// watch(() => {
//   if (data.d) return data.a + data.d.a;
//   return data.a;
// }, (oldVal, value) => {
//   console.log('watch 3 callback', oldVal, value);
// });

// const origin = data.c;
// data.a += 1;
// data.b += 1;
// data.c.d += 1;
// data.c = { d: 1 };
// data.c.d = 10;
// origin.d = 15; // 不会被触发
// data.d = { a: 1 }; // 添加新属性
// data.d.a++;

// TEST 2: 数组
// const target = {
//   list: [1, 2]
// };

// const data = proxy(target);

// const watcher = watch(() => {
//   return target.list.join('')
// }, (oldVal, value) => {
//   console.log('watch callback', oldVal, value);
// });

// target.list[0]++;
// target.list[1]++;
// target.list.push(3);
// target.list[3] = 4;

// TEST 3: 数组嵌套对象
// const target = {
//   list: [{ id: 1 }]
// };

// const data = proxy(target);

// const watcher = watch(() => {
//   return target.list.map(x => x.id).join('')
// }, (oldVal, value) => {
//   console.log('watch callback', oldVal, value);
// });

// target.list[0].id++;
// target.list.push({ id: 2 }); // push会触发设置值和设置length两个变化，这里可以比较value和oldValue或watcher入queue来实现
// target.list[1].id++;
// target.list.pop();
// target.list[1] = { id: 2}; 

// TEST 4: 重复绑定
// const target1 = { a: 1 };
// const target2 = { a: target1 };
// const target3 = { a: target1 };
// const data1 = proxy(target1);
// const data2 = proxy(target1);
// const data3 = proxy(target2);
// const data4 = proxy(target3);

// watch(() => {
//   return data1.a;
// }, (oldVal, value) => {
//   console.log('watch 1 callback', oldVal, value);
// });
// watch(() => {
//   return data2.a;
// }, (oldVal, value) => {
//   console.log('watch 2 callback', oldVal, value);
// });
// watch(() => {
//   return data3.a.a;
// }, (oldVal, value) => {
//   console.log('watch 3 callback', oldVal, value);
// });
// watch(() => {
//   return data4.a.a;
// }, (oldVal, value) => {
//   console.log('watch 4 callback', oldVal, value);
// });

// data1.a++;
